package com.vichat.common.rudp.thread;

import com.vichat.common.rudp.RudpBlockData;
import com.vichat.common.rudp.RudpDataUtil;
import com.vichat.common.rudp.RudpMonitorUtil;
import com.vichat.common.rudp.RudpTransData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.SocketAddress;
import java.nio.ByteBuffer;

public class RudpNioReceiveThread implements Runnable {

    private static transient Logger logger = LoggerFactory.getLogger(RudpNioReceiveThread.class);
    SocketAddress srcAddress = null;
    ByteBuffer buffer = null;

    public RudpNioReceiveThread(SocketAddress insrcAddress, ByteBuffer inbuffer) {
        srcAddress = insrcAddress;
        buffer = inbuffer;
    }

    public void run() {
        long startIme = System.currentTimeMillis();
        int msgtype = 1;
        if (RudpMonitorUtil.monitorFlag) {
            RudpMonitorUtil.startReceiveThread();
        }


        try {
            buffer.flip();
            byte[] bt = new byte[buffer.limit()];
            buffer.get(bt);
            buffer.clear();


            StringBuilder res = new StringBuilder();
            for (int i = 0; i < bt.length; i++) {
                res.append(i).append(",").append(bt[i]).append("|");
            }
            logger.debug("\n!!读取此次数据" + res.toString());

            RudpBlockData blockData = RudpDataUtil.unmarshalBlockData(bt);

            long step1 = System.currentTimeMillis() - startIme;
            if (blockData.msgType == 0) {

                msgtype = 0;
                if (RudpMonitorUtil.monitorFlag) {
                    //放入trans监控
                    RudpMonitorUtil.startTrans(blockData.getStringTrans(), startIme);
                }


                try {
                    //发送ack
                    RudpBlockData ackData = new RudpBlockData(blockData);
                    ackData.desAddress = srcAddress;
                    RudpDataUtil.sendAckPacket(ackData);
                } catch (Exception e) {
                    logger.error("发送ACK报文失败" + blockData.getBlockKey() + "-" + srcAddress.toString(), e);
                }

                long step2 = System.currentTimeMillis() - startIme;


                try {
                    RudpTransData transData = RudpDataUtil.assembleData(blockData);
                    if (transData.blockNum == transData.blockList.size()) {
                        if (RudpMonitorUtil.monitorFlag) {
                            //放入trans监控
                            RudpMonitorUtil.endTrans(transData.getStringTrans(), System.currentTimeMillis());
                        }
                        //发送业务处理线程进行处理
                        transData.indicated = true;
                        transData.remoteAddr = srcAddress;

                        //String jsonString = RudpDataUtil.assembelBusiString(transData);
                        //logger.error("报文接受成功:"+jsonString);
                        logger.debug("!!!!!!!!数据包接受成功" + blockData.getStringTrans() + blockData.blockId);
                        RudpDataUtil.addBusiQueue(transData);
                    } else {
                        logger.debug("!!!!!!!!多包处理，总共" + transData.blockNum + ",已收到" + transData.receiveNum + "," + blockData.getStringTrans() + blockData.blockId);
                    }


                } catch (Exception e) {
                    logger.debug("事务数据组装失败" + blockData.getBlockKey(), e);
                }

                long step3 = System.currentTimeMillis() - startIme;

                if (step3 > 10) {
                    logger.debug("!!!!!!!!处理业务报文超时" + step3 + "," + step2 + "," + step1);
                }

            } else {
                //如果接受到的是ack,则设置接受标志
                RudpDataUtil.receiveAckPacket(blockData);

            }


        } catch (Exception e) {
            logger.error("数据接收处理失败", e);
        }

        if (RudpMonitorUtil.monitorFlag) {
            long costtime = System.currentTimeMillis() - startIme;
            RudpMonitorUtil.endReceiveThread(costtime, msgtype);
        }
    }
}   
